package com.data;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.TreeMap;

public class IdManager {
	
	//**************************************************************************************************
	//	Constructor.
	//**************************************************************************************************
	
	private IdManager() {
		loadIndex();
	}
	
	private static IdManager idManager;
	
	public static IdManager getInstance() {
		if (idManager == null)
			idManager = new IdManager();
		return idManager;
	}
	
	//**************************************************************************************************
	//	Constants.
	//**************************************************************************************************
	
	// Id prefixes used to identify between different design components.
	public static final byte TEMPLATE_PREFIX 	= 0x00; // template prefix
	public static final byte THEME_PREFIX 		= 0x01; // theme prefix...
	public static final byte SCREEN_PREFIX 		= 0x02;
	public static final byte MENU_PREFIX		= 0x03;
	public static final byte ENTRY_PREFIX 		= 0x04;
	public static final byte BANNER_PREFIX 		= 0x05;
	public static final byte BUTTON_PREFIX 		= 0x06;
	public static final byte IMAGE_PREFIX 		= 0x07;
	public static final byte TEXT_PREFIX 		= 0x08;

	public static final String IDS_FILE_PATH = "./data/";
	public static final String IDS_FILE = "components.ids";
	
	public static final TreeMap <Byte, String> COMPONENT_TYPES = new TreeMap <Byte, String>() {
		
		private static final long serialVersionUID = 1L;
		
		{
			put(TEMPLATE_PREFIX, "Template");
			put(THEME_PREFIX, "Theme");
			put(SCREEN_PREFIX, "Screen");
			put(MENU_PREFIX, "Menu");
			put(ENTRY_PREFIX, "Entry");
			put(BANNER_PREFIX, "Banner");
			put(BUTTON_PREFIX, "Button");
			put(IMAGE_PREFIX, "Image");
			put(TEXT_PREFIX, "Text");
		}
	};
	
	//**************************************************************************************************
	//	Attributes.
	//**************************************************************************************************
	
	private static int lastIdAssigned;
	
	//**************************************************************************************************
	//	Methods that exports this Class (Public Methods).
	//**************************************************************************************************
	
	/**
	 * Generates an id checking that it does not already exist.
	 * */
	public static int getNewId (byte prefix) {
		lastIdAssigned++;
		int aux = putPrefix(lastIdAssigned, prefix);
		return aux;
	}
	
	/**
	 * Receives an id and returns true if that id already exists. False if not.
	 * */
	public static boolean existId(int id) {
		return true;
	}
	
	/**
	 * Erase the prefix of an id. This this turning the 8 most significant bits to 0. 
	 * @param id Id with prefix.
	 * @return int without the prefix.
	 * */
	public static int erasePrefix(int id) {
		return (id & 0x001111);
	}
	
	/**
	 * Puts the prefix to an id. This this adding the prefix in the 8 most significant bits to 0. 
	 * @param id Id without prefix.
	 * @param prefix Prefix to be added.
	 * @return int with the prefix.
	 * */
	public static int putPrefix(int id, byte prefix) {
		int a = id;
		int b = prefix;
		int c = b << 16;
		int aux = (a | c);
		return aux;
	} 
	
	/**
	 * Receives an id of a design component and it determines the name of the class that the id belongs to.
	 * */
	public static String resolveId (short id) {
		return "";
	} 
	
	/**
	 * Receives an id and returns the prefix.
	 * @param id
	 * @return byte Prefix. 
	 * */
	public static byte getPrefixById (int id){
		int aux = id >> 16;
		return (byte) aux; 
	}
	
	//**************************************************************************************************
	//	Inner methods.
	//**************************************************************************************************
	
	/**
	 * Loads the last index used from a text file.
	 * */
	private void loadIndex() {
		File fd = new File(IDS_FILE_PATH.concat(IDS_FILE));
		try {
			Scanner reader = new Scanner(fd);
			int lastId = reader.nextShort();
			lastIdAssigned = erasePrefix(lastId);
		} catch (FileNotFoundException e) {
			// TODO: launch an error frame. Show a SEVERAL message to the user that an error loading the id's file occurred, 
			// and that all changes made wont have effect.
		}
	}
	
}
